package com.yangxk.kadmin.web.module.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yangxk.kadmin.common.base.AbstractService;
import com.yangxk.kadmin.common.beans.Page;
import com.yangxk.kadmin.common.exception.BizException;
import com.yangxk.kadmin.common.support.BeanValidator;
import com.yangxk.kadmin.common.support.generator.IdGenerator;
import com.yangxk.kadmin.common.util.MD5Util;
import com.yangxk.kadmin.common.util.StringUtil;
import com.yangxk.kadmin.common.util.ValidUtil;
import com.yangxk.kadmin.web.common.Const;
import com.yangxk.kadmin.web.common.SessionUserHolder;
import com.yangxk.kadmin.web.common.datascope.DataScope;
import com.yangxk.kadmin.web.common.enumeration.ResponseCode;
import com.yangxk.kadmin.web.module.system.form.*;
import com.yangxk.kadmin.web.module.system.mapper.RoleMapper;
import com.yangxk.kadmin.web.module.system.mapper.UserMapper;
import com.yangxk.kadmin.web.module.system.po.Auth;
import com.yangxk.kadmin.web.module.system.po.Role;
import com.yangxk.kadmin.web.module.system.po.User;
import com.yangxk.kadmin.web.module.system.po.UserRole;
import com.yangxk.kadmin.web.module.system.service.AuthService;
import com.yangxk.kadmin.web.module.system.service.UserService;
import com.yangxk.kadmin.web.module.system.vo.AuthTree;
import com.yangxk.kadmin.web.module.system.vo.UserRoleVo;
import com.yangxk.kadmin.web.module.system.vo.UserVo;
import com.yangxk.upload.provider.UploadProvider;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;

@Service
public class UserServiceImpl extends AbstractService<User, Long> implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private AuthService authService;
    @Autowired
    private UploadProvider uploadProvider;

    @Override
    public User checkLogin(LoginForm loginForm) {
        BeanValidator.check(loginForm);

        User user = userMapper.findByKeyWord(loginForm.getUsername());
        if (user == null ||
                !user.getPassword().equalsIgnoreCase(MD5Util.md5(loginForm.getPassword())))
            throw new BizException(ResponseCode.LOGIN_FAIL);

        // 账号被禁用
        if (Const.SYS_STATUS.DISABLE.equalsIgnoreCase(user.getStatus())) {
            throw new BizException(ResponseCode.LOGIN_ACCOUNT_DISABLE);
        }

        user.setPassword(null);

        return user;
    }

    @Override
    @DataScope
    public Page<UserVo> findByPage(UserQueryForm queryForm) {

        PageHelper.startPage(queryForm.getPageNum(), queryForm.getPageSize());
        List<UserVo> users = userMapper.findByPage(queryForm);

        PageInfo<UserVo> pageInfo = new PageInfo<>(users);
        return new Page<UserVo>(pageInfo);
    }

    @Override
    public UserVo findById(long userId) {
        User user = userMapper.selectByPrimaryKey(userId);

        UserVo result = new UserVo();
        if (user == null)
            return result;
        BeanUtils.copyProperties(user, result);

        return result;
    }

    @Override
    @Transactional
    public Long addUser(UserInsertForm insertForm) {
        BeanValidator.check(insertForm);
        User user = new User();
        BeanUtils.copyProperties(insertForm, user);

        checkPhoneAndEmail(null, user.getPhone(), user.getEmail());

        user.setId(IdGenerator.getId());
        user.setPassword(MD5Util.md5(user.getPassword()));
        user.setStatus(Const.SYS_STATUS.ENABLE);
        user.setFirstName(user.getUsername().substring(0,1));
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        userMapper.insertSelective(user);

        return user.getId();
    }

    @Override
    @Transactional
    public void updateUser(UserUpdateForm updateForm) {
        BeanValidator.check(updateForm);
        User user = new User();
        BeanUtils.copyProperties(updateForm, user);

        checkPhoneAndEmail(user.getId(), user.getPhone(), user.getEmail());

        user.setFirstName(user.getUsername().substring(0,1));
        user.setUpdateTime(new Date());

        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    @Transactional
    public void deleteUser(Long id) {
        User user = userMapper.selectByPrimaryKey(id);
        user.setDelFlag(Const.SYS_DEL_FLAG.DEL);

        userMapper.updateByPrimaryKeySelective(user);
        // 删除sys_user_role中的记录
        roleMapper.deleteRoleByUser(user.getId());
    }

    @Override
    @Transactional
    public void deleteUser(String ids) {
        String[] arr = StringUtil.str2Arr(ids);
        for (String id : arr) {
            deleteUser(Long.valueOf(id));
        }
    }

    /**
     * 查询用户角色
     * create by yangxk on 2019/3/4 13:28
     */
    @Override
    public UserRoleVo findUserRole(long userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null)
            throw new BizException(ResponseCode.SELECT_CHECK_NULL);

        // 查询所有角色
        List<Role> roles = roleMapper.selectList(new RoleQueryForm());

        // 查询用户角色
        List<Long> userRole = roleMapper.findUserRole(userId);

        UserRoleVo ur = new UserRoleVo();
        ur.setRoles(roles);
        ur.setSelected(userRole);

        return ur;
    }

    /**
     * 设置用户角色
     * create by yangxk on 2019/3/4 13:32
     */
    @Override
    @Transactional
    public void setUserRole(long userId, Long[] roleIds) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null)
            throw new BizException(ResponseCode.ILLEGAL_OPERATE);

        // 删除用户现有角色
        roleMapper.deleteRoleByUser(userId);

        // 重新添加角色
        if (ValidUtil.isEmpty(roleIds))
            return;

        List<UserRole> list = new ArrayList<>();
        UserRole ur = null;
        for (Long roleId : roleIds) {
            ur = new UserRole();
            ur.setId(IdGenerator.getId());
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            ur.setCreateTime(new Date());
            ur.setUpdateTime(new Date());

            list.add(ur);
        }

        roleMapper.insertUserRole(list);
    }


    /**
     * 获取当前登录用户的权限信息
     * create by yangxk on 2018/9/21 16:45
     */
    @Override
    public List<AuthTree> findAuthTreeOfUser(Long id) {
        return authService.queryUserAuthTree(id);
    }

    /**
     * 获取当前登录用户的权限集合
     * create by yangxk on 2018/10/19 15:53
     */
    @Override
    public List<Auth> findUserAuth(long id) {
        return authService.queryUserAuth(id);
    }


    /**
     * 查询用户的数据权限
     * create by yangxk on 2019/2/2 11:33
     */
    @Override
    public List<Long> findUserDataScope(long userId) {
        String deptIds = roleMapper.findUserRoleDept(userId);
        if (ValidUtil.isEmpty(deptIds))
            return new ArrayList<>();
        String[] ids = StringUtil.str2Arr(deptIds, ",");

        Set<Long> set = new HashSet<>();
        for (String id : ids) {
            set.add(Long.valueOf(id));
        }

        List<Long> result = new ArrayList<>(set);

        return result;
    }
    /**
     * 更新当前登录用户信息
     * create by yangxk 2018/10/29 21:00
     */
    @Override
    @Transactional
    public void updateSessionUser(UserUpdateForm updateForm) {
        BeanValidator.check(updateForm);
        if (SessionUserHolder.getUserId() != updateForm.getId())
            throw new BizException(ResponseCode.ILLEGAL_OPERATE);

        checkPhoneAndEmail(updateForm.getId(), updateForm.getPhone(), updateForm.getEmail());

        User user = new User();
        BeanUtils.copyProperties(updateForm, user);

        user.setFirstName(user.getUsername().substring(0,1));
        user.setUpdateTime(new Date());

        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 修改当前登录用户密码
     * create by yangxk 2018/10/29 21:37
     */
    @Override
    @Transactional
    public void updateSessionUserPassword(UserPwdForm pwdForm) {
        BeanValidator.check(pwdForm);

        if (SessionUserHolder.getUserId() != pwdForm.getId())
            throw new BizException(ResponseCode.ILLEGAL_OPERATE);

        User before = userMapper.selectByPrimaryKey(pwdForm.getId());
        // 原密码错误
        if (!before.getPassword().equalsIgnoreCase(MD5Util.md5(pwdForm.getOldPwd())))
            throw new BizException(ResponseCode.OLD_PASSWORD_ERROR);

        User user = new User();
        user.setId(pwdForm.getId());
        user.setPassword(MD5Util.md5(pwdForm.getNewPwd()));
        user.setUpdateTime(new Date());

        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 上传头像
     * create by yangxk 2019/2/26 19:47
     */
    @Override
    @Transactional
    public String uploadAvatar(long userId, String filename, InputStream in) {
        if (ValidUtil.isEmpty(filename) || in == null)
            throw new BizException(ResponseCode.ILLEGAL_PARAM);

        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null)
            throw new BizException(ResponseCode.UPLOAD_ERROR);

        String url = uploadProvider.upload(filename, in);

        user.setAvatar(url);

        userMapper.updateByPrimaryKeySelective(user);

        return url;
    }


    private void checkPhoneAndEmail(Long userId, String phone, String email) {
        User before = null;
        if (userId != null) {
            before = userMapper.selectByPrimaryKey(userId);
        }

        if (before != null && !phone.equals(before.getPhone())) {
            User check = userMapper.findByKeyWord(phone);
            if (check != null)
                throw new BizException(ResponseCode.PHONE_EXIST);
        }

        if (before != null && !email.equals(before.getEmail())) {
            User check = userMapper.findByKeyWord(email);
            if (check != null)
                throw new BizException(ResponseCode.EMAIL_EXIST);
        }

    }

}
